Skip to content

[UI] Fix stale cache causing 'Table does not exist' error#4075

Open
j1wonpark wants to merge 2 commits intoapache:masterfrom
j1wonpark:fix/fix-ui-cache
Open

[UI] Fix stale cache causing 'Table does not exist' error#4075
j1wonpark wants to merge 2 commits intoapache:masterfrom
j1wonpark:fix/fix-ui-cache

Conversation

@j1wonpark
Copy link
Contributor

Why are the changes needed?

When a table is deleted or no longer exists, the UI may still attempt to load it from stale cache (localStorage), causing a "Table does not exist" error. This creates a poor user experience as the UI gets stuck trying to load a non-existent table.

This fix ensures that when a table is not found:

  1. The stale cache entry is cleared from localStorage
  2. The user is redirected to the tables list page
  3. The component state is properly reset

Brief change log

  • amoro-web/src/views/tables/components/Details.vue:

    • Added tableNotFound emit event to notify parent component when table doesn't exist
    • Clear localStorage cache when API returns "not exist" or "not found" error
    • Redirect to /tables page when table is not found
  • amoro-web/src/views/tables/index.vue:

    • Added handleTableNotFound handler to reset baseInfo state
    • Connected the tableNotFound event from UDetails component

How was this patch tested?

  • Run test locally before making a pull request

  • Add screenshots for manual tests if appropriate

    • Manually tested by deleting a table while viewing it in the UI
    • Verified that the stale cache is cleared and user is redirected properly

Documentation

  • Does this pull request introduce a new feature? no
  • If yes, how is the feature documented? not applicable>>

Signed-off-by: j1wonpark <jpark92@outlook.kr>
@github-actions github-actions bot added the module:ams-dashboard Ams dashboard module label Feb 5, 2026
Copy link
Contributor

@majin1102 majin1102 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this. This is meaningful fix!

Left a comment(actually raised by AI), please take a look

}
catch (error) {
const errorMessage = (error as Error)?.message || ''
const isNotFoundError = /not exist|not found/i.test(errorMessage)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestions from AI:

There is a potential race condition in getTableDetails when the route changes while a previous request is still in flight. params is a computed value based on route.query, so during the await getTableDetail(...) call the user can switch from table A to table B, causing params.value to point to table B.

When the slow request for table A finally fails with "Table does not exist" / "table not found", the catch block reads catalogName, dbName, and tableName again from params.value. At that time params.value may already refer to table B, so we will:

  • remove the cached table key from localStorage,
  • emit tableNotFound for table B, and
  • redirect the user back to /tables.
  • This means a valid table B can be mistakenly treated as non-existent if a previous request for table A fails later, which is confusing for users.

Suggestion: take a snapshot of the parameters at the beginning of getTableDetails and use that snapshot consistently in both the request and the error handling, for example:

const getTableDetails = async () => {
  isLoading.value = true;
  const requestParams = { ...params.value };
  const { catalogName, dbName, tableName } = requestParams;
  try {
    const res = await getTableDetail({
      type: requestParams.tableType,
      name: tableName,
      database: dbName,
      catalog: catalogName,
    });
    tableDetails.value = res?.data?.details;
    getTableOptimizeInfo();
  } catch (error: any) {
    const e = error as AxiosError<any> & { data: { message?: string } };
    const message = e?.data?.message;
    if (message && (message.includes("Table does not exist") || message.includes("table not found"))) {
      localStorage.removeItem(STORAGE_TABLE_KEY);
      emit("tableNotFound", `${catalogName}/${dbName}/${tableName}`);
      router.replace({ path: "/tables", query: {} });
      return;
    }
  } finally {
    isLoading.value = false;
  }
};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review! Fixed in f716e97 — params are now snapshot at the start of getTableDetails() so that both the API call and the catch block use the same values, preventing the race condition when the route changes during an in-flight request.

…request

Signed-off-by: Jiwon Park <22048252+j1wonpark@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

module:ams-dashboard Ams dashboard module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants